import {
	nextTick
} from "vue";

class ImageTool {

	#type = ''; //平台类型
	#watermark = []; //水印内容
	#maxSize = -1; //图片压缩最大值

	constructor(arg) {
		// #ifdef H5
		this.#type = "h5"
		// #endif
		this.#watermark = arg.watermark || []
		if (this.#watermark.length > 0) {
			this.#maxSize = 500 // 绘制水印就必定压缩500k以内
		} else {
			this.#maxSize = arg.maxSize || 1024
		}
	}
	/**
	 * 选择或拍摄照片
	 */
	#chooseImage() {
		return new Promise((resolve, reject) => {
			uni.chooseImage({
				count: 1,
				sizeType: ['compressed'],
				sourceType: ['album', 'camera'],
				success: (result) => {
					const file = result.tempFiles[0]
					resolve(file)
				},
				fail: (result) => {
					console.error('选择失败', result)
					// #ifdef APP
					if (result.errMsg.indexOf("chooseImage:fail No Permission") > -1) {
						uni.showModal({
							title: "请检查相机与相册权限是否正常开启",
							content: "用于拍摄或选择照片上传服务器",
							showCancel: false,
							success: (res) => {
								if (res.confirm) {
									uni.openAppAuthorizeSetting()
								}
							}
						});
					}
					// #endif
					reject(result)
				},
				complete() {}
			})
		})
	}
	/**
	 * @param {Object} param｛
	 * chooseOk ，选择后调用
	 * addWaterBefore,绘制水印前调用，h5模式需要
	 * ｝
	 */
	choose(param) {
		return new Promise((resolve, reject) => {
			this.#chooseImage().then(file => {
				param.chooseOk && param.chooseOk(file)
				if (this.#type === 'h5') {
					if (this.#watermark.length > 0) {
						this.#addWatermarkH5(file.path).then(res => {
							resolve(res)
						})
					} else if (this.#maxSize > 0) {
						this.#compressImageH5({
							path: file.path
						}).then(res => {
							resolve(res)
						})
					} else {
						resolve(file.path)
					}
				} else {
					if (this.#watermark.length > 0) {
						this.#addWatermarkApp(file.path, param).then(res => {
							resolve(res)
						})
					} else if (this.#maxSize > 0) {
						this.#compressImageApp(file.path).then(res => {
							resolve(res)
						})
					} else {
						resolve(file.path)
					}
				}
			})
		})
	}

	/**
	 * h5 图片加水印
	 * @param {Object} src
	 */
	#addWatermarkH5(src) {
		uni.showLoading({
			title: '正在绘制水印...'
		})
		return new Promise((resolve, reject) => {
			let canvas = document.createElement('canvas');
			let ctx = canvas.getContext('2d')
			let img = new Image()
			img.src = src
			img.onload = () => {
				// 绘制图像到 canvas
				let w = img.width
				let h = img.height
				const max = 750
				if (img.width > max) {
					h = h / (w / max);
					w = max;
				}
				canvas.width = w;
				canvas.height = h;
				ctx.drawImage(img, 0, 0, w, h);

				let fontSize = 30
				ctx.font = `${fontSize}px 微软雅黑`
				ctx.fillStyle = '#ffffff'
				ctx.textAlign = 'left'
				ctx.textBaseline = 'middle'
				// 750宽只能容纳30px文字24个
				const maxTextLength = (max / fontSize - 2) * 2
				let x = 30
				let y = 80
				this.#watermark.forEach(w => {
					const byteLength = this.#getByteSize(w)
					if (byteLength > maxTextLength) {
						let start = 0
						let length = maxTextLength
						while (start < byteLength) {
							const text = this.#subStrByByte(w, start, length)
							ctx.fillText(text, x, y)
							y += 35
							start = start + length
						}
					} else {
						ctx.fillText(w, x, y)
						y += 35
					}

				})

				canvas.toBlob((fileSrc) => {
					this.#compressImageH5({
						blob: fileSrc
					}).then(res => {
						resolve(res)
					})
				}, "image/jpeg", 1)
			}
		})
	}

	/**
	 * app 图片加水印
	 * @param {Object} filePath
	 */
	#addWatermarkApp(filePath, callback) {
		uni.showLoading({
			title: '正在绘制水印...'
		})
		return new Promise((resolve, reject) => {
			uni.getImageInfo({
				src: filePath,
				success: (img) => {
					let w = img.width
					let h = img.height
					const max = 750
					if (img.width > max) {
						h = h / (w / max);
						w = max;
					}
					callback.addWaterBefore && callback.addWaterBefore({
						width: w,
						height: h
					})
					setTimeout(() => {
						const ctx = uni.createCanvasContext('canvasWaterMark')
						ctx.drawImage(filePath, 0, 0, w, h);

						let fontSize = 30
						ctx.font = `${fontSize}px 微软雅黑`
						ctx.fillStyle = '#ffffff'
						ctx.textAlign = 'left'
						ctx.textBaseline = 'middle'
						// 750宽只能容纳30px文字24个
						const maxTextLength = (max / fontSize - 2) * 2
						let x = 30
						let y = 80
						this.#watermark.forEach(w => {
							const byteLength = this.#getByteSize(w)
							if (byteLength > maxTextLength) {
								let start = 0
								let length = maxTextLength
								while (start < byteLength) {
									const text = this.#subStrByByte(w, start,
										length)
									ctx.fillText(text, x, y)
									y += 35
									start = start + length
								}
							} else {
								ctx.fillText(w, x, y)
								y += 35
							}
						})

						ctx.draw(false, () => {
							uni.canvasToTempFilePath({
								canvasId: 'canvasWaterMark',
								fileType: 'jpg',
								quality: 0.5,
								success: res => {
									this.#compressImageApp(res
										.tempFilePath).then(
										res => {
											resolve(res)
										})
								},
								fail: () => {
									reject('水印绘制失败')
								}
							});
						})
					}, 500)
				}
			})
		})
	}
	#compressImageApp(imgSrc, quality = 50) {
		uni.showLoading({
			title: '正在压缩...'
		})
		return new Promise((resolve, reject) => {
			uni.getFileInfo({
				filePath: imgSrc,
				success: (resFileInfo) => {
					if (this.#maxSize < 0 || resFileInfo.size < this.#maxSize * 1024 ||
						quality <= 10) {
						resolve(imgSrc)
					} else {
						uni.compressImage({
							src: imgSrc,
							quality: quality,
							success: res => {
								this.#compressImageApp(res.tempFilePath, quality -
										10)
									.then(
										res => {
											resolve(res)
										})
							},
							fail: () => {
								resolve(imgSrc)
							}
						})
					}
				}
			})
		})
	}
	/**
	 * h5图片压缩
	 */
	#compressImageH5(option, quality = 0.5) {
		const {
			path,
			blob
		} = option
		uni.showLoading({
			title: '正在压缩...'
		})
		return new Promise((resolve, reject) => {
			let imgSrc = path || window.URL.createObjectURL(blob);
			uni.getFileInfo({
				filePath: imgSrc,
				success: (resFileInfo) => {
					if (this.#maxSize < 0 || resFileInfo.size < this.#maxSize * 1024 ||
						quality <= 0.1) {
						let files = path ? path : new window.File(
							[blob],
							Date.now() + ".jpeg", {
								type: blob.type
							}
						)
						resolve(files)
					} else {
						let canvas = document.createElement('canvas');
						let ctx = canvas.getContext('2d')
						let img = new Image()
						img.src = imgSrc
						img.onload = () => {
							// 绘制图像到 canvas
							canvas.width = img.width;
							canvas.height = img.height;
							ctx.drawImage(img, 0, 0, img.width, img.height);
							canvas.toBlob((fileSrc) => {
								this.#compressImageH5({
									blob: fileSrc
								}, quality - 0.1).then(
									res => {
										resolve(res)
									})
							}, "image/jpeg", quality)
						}
					}
				}
			})
		})
	}

	/**
	 * 获取字符串字节长度
	 */
	#getByteSize(val) {
		let n = 0
		for (let i = 0; i <= val.length; i++) {
			n += val.charCodeAt(i) > 255 ? 2 : 1;
		}
		return n;
	}
	/**
	 * 按照字节截取长度
	 * @param {Object} val
	 * @param {Object} start
	 * @param {Object} length
	 */
	#subStrByByte(val, start, length) {
		var str = new String(val);
		let result = ''
		var bytesCount = 0;
		var startSize = 0;
		var handelSize = 0;
		for (var i = 0, n = str.length; i < n; i++) {
			const s = str[i]
			var c = str.charCodeAt(i);
			let charSize = 1
			if ((c >= 0x0001 && c <= 0x007e) || (0xff60 <= c && c <= 0xff9f)) {
				charSize = 1;
			} else {
				charSize = 2;
			}
			bytesCount += charSize
			if (bytesCount > start) {
				if (handelSize < length) {
					if (!(start != 0 && handelSize === 0 && charSize == 2)) {
						result += s
					}
					handelSize += charSize
				}
			}

		}
		return result;
	}
}
export default ImageTool